import json
import logging
import re

from django import http
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.carts.utils import merge_cookie_to_redis
from apps.goods.models import SKU
from apps.users.models import User, Address
from apps.users.utils import generic_verify_email_url, check_verfy_email_token
from utils.response_code import RETCODE
from utils.views import LoginRequiredJSONMixin

logger = logging.getLogger('django')



class RegisterView(View):
    def get (self, request) :
        return render(request,'register.html')
    def post(self,request):
        data = request.POST
        username=data.get("username")
        password = data.get("password")
        password2=data.get("password2")
        mobile=data.get("mobile")
        allow=data.get("allow")
        sms_code_client=data.get('sms_code')
        if not all([username,password,password2,mobile,allow,sms_code_client]):
            return http.HttpResponseBadRequest("参数不全")
        if  not re.match(r'^[0-9a-zA-Z_-]{5,20}$',username):
            return http.HttpResponseBadRequest("用户名不满足条件")
        if  not re.match(r'^[0-9a-zA-Z_-]{8,20}$',password):
            return http.HttpResponseBadRequest("密码格式不满足")
        if  password2 != password:
            return http.HttpResponseBadRequest('俩次密码输入不一样')
        if  not re.match(r'^1[1-9]\d{9}$',mobile):
            return http.HttpResponseBadRequest("手机格式不满足条件")
        if  allow !="on":
            return http.HttpResponseBadRequest("您未同意协议")
        redis_conn= get_redis_connection("code")
        sms_code_server=redis_conn.get('sms_%s'%mobile)
        if not sms_code_server :
            return  http.HttpResponseBadRequest("验证码已经过期")
        # if sms_code_server.decode() !=sms_code_client:
        if sms_code_server.decode() != sms_code_client:

            return  http.HttpResponseBadRequest('短信验证码不一致')
        try :
            user=User.objects.create_user(
                username=username,
                password=password,
                mobile=mobile,
                                          )
        except  Exception as  e:

            logger.error(e)
            return render(request,'register.html',context={'register_message':'创建用户失败'})
        #状态保持
        login(request,user)
        return  redirect(reverse('contents:index'))
        # return http.HttpResponseBadRequest('ok')
    #判断用户名是否重复


class RegisterUsernameCountView(View):
    def get (self,request,username):
        count=User.objects.filter(username=username).count()
        return http.JsonResponse({'count': count},)


class RegisterMobileCountView(View):
    def get (self,request,mobile):
        count=User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({'count':count})



class LoginView(View):
    def get(self, request):
        return render(request,'login.html')
    def post(self,request):
        data=request.POST
        username=data.get("username")
        password=data.get("password")
        remembered=data.get("remembered")
        if not all([username,password]):
            return http.HttpResponseBadRequest('参数不齐')
        if  not re.match(r'^[0-9a-zA-Z_-]{5,20}$',username):
            return http.HttpResponseBadRequest("用户名不满足条件")
        if  not re.match(r'^[0-9a-zA-Z_-]{8,20}$',password):
            return http.HttpResponseBadRequest("密码格式不满足")
        user=authenticate(username=username,password=password)
        if user is None:
            return http.HttpResponseBadRequest('用户名，密码错误')

        login(request,user)

        if remembered !="on":
            request.session.set_expiry(0)

        else:
           request.session.set_expiry(None)
        next=request.GET.get('next')
        if next:
            response=redirect(next)
        else:
            response=redirect(reverse('contents:index'))

        # if remembered != 'on':
        #     # 说明不需要记住
        #     response.set_cookie('username', user.username, max_age=0)
        # else:
        #     # 需要记住
        #     response.set_cookie('username', user.username, max_age=14 * 24 * 3600)
        #
        # return response
        if remembered != "on":
           response.set_cookie("username",user.username,max_age=None )

        else:
            response.set_cookie("username", user.username, max_age=14*24*3600)

        #在这里合并购物车
        response=merge_cookie_to_redis(request,user,response)


        return  response


class LogoutView(View):
    def get(self,request):
        logout(request)
        response=redirect(reverse('contents:index'))
        response.delete_cookie("username")
        return response


class UserInfoView(LoginRequiredMixin,View):


    def get(self,request):
        context={
            'username':request.user.username,
            'mobile':request.user.mobile,
            'email': request.user.email,
            'email_active':request.user.email_active
        }



        return render(request,'user_center_info.html',context=context)



class EmailView(LoginRequiredMixin,View):
    def put (self,request):
        # data=request.POST
        body=request.body
        body_str=body.decode()
        data=json.loads(body_str)

        email = data.get('email')
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$',email):
            return http.JsonResponse({'code':RETCODE.PARAMERR,'errmsg':'参数错误'})
        try:

            request.user.email=email
            request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code':RETCODE.DBERR,'ermsg':'更新错误'})
        verify_url=generic_verify_email_url(request.user.id)
        subject='美多商城'
        message=''
        from_email="18335445063@163.com"
        recipient_list=[email]
        html_message = '<p>尊敬的用户您好！</p>' \
                       '<p>感谢您使用美多商城。</p>' \
                       '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                       '<p><a href="%s">%s<a></p>' % (email, verify_url, verify_url)
        # send_mail(
        #     subject=subject,
        #     message=message,
        #     from_email=from_email,
        #     recipient_list=recipient_list,
        #     html_message=html_message
        # )
        from celery_tasks.email.tasks import send_verify_email
        send_verify_email.delay(
                subject=subject,
                message=message,
                from_email=from_email,
                recipient_list=recipient_list,
                 html_message=html_message

        )

        return http.JsonResponse({'code':RETCODE.OK,'ermsg':'ok'})


class EmailVerifyView(View):
    def get(self,request):
        token=request.GET.get('token')
        if token is None:
            return  http.HttpResponseBadRequest('参数错误')
        user_id = check_verfy_email_token(token)
        if user_id is None:
            return http.HttpResponseBadRequest('参数错误')
        try:
            user=User.objects.get(pk=user_id)
            if user is not None:
                user.email_active=True
                user.save()

        except User.DoesNotExist:
            return http.HttpResponseBadRequest('参数错误')


        return redirect(reverse('users:info'))



class AddressView(View):
    def get(self,request):
        addresses = Address.objects.filter(user=request.user, is_deleted=False)

        addresses_list = []
        for address in addresses:
            addresses_list.append({
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "province_id": address.province_id,
                "city": address.city.name,
                "city_id": address.city_id,
                "district": address.district.name,
                "district_id": address.district_id,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            })

        context = {
            'addresses': addresses_list,
            'default_address_id': request.user.default_address_id

        }
        return render(request, 'user_center_site.html', context=context)


#LoginRequiredJSONMixin 局部刷新　　　
class CreateAddressView(LoginRequiredJSONMixin,View):

    def post (self,request):

        count=Address.objects.filter(user=request.user,is_deleted=False).count()
        if count > 20:
            return http.JsonResponse({'code':RETCODE.THROTTLINGERR,'errmsg':'个数超过上限'})



        # if request .user.is_authenticated
        json_dict=json.loads(request.body.decode())
        receiver = json_dict.get('receiver')#收货人
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')
        # 校验参数
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.HttpResponseBadRequest('缺少必传参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')
        try:
            address=Address.objects.create(
                user=request.user,
                title=receiver,
                receiver=receiver,
                province_id=province_id,
                city_id=city_id,
                district_id=district_id,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email

            )


            if not request.user.default_address:
                request.user.default_address=address
                request.user.save()
        except Exception as  e:
            logger.error(e)
            return http.JsonResponse({'code':RETCODE.DBERR,'errmsg':'数据库操作失败'})
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }

        # 响应保存结果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok', 'address': address_dict})



class UpdateDestoryAddressView(LoginRequiredJSONMixin,View):
    def put (self,request,address_id):
        json_dict=json.loads(request.body.decode())
        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')
        try:
            Address.objects.filter(pk=address_id).update(
                user=request.user,
                title=receiver,
                receiver=receiver,
                province_id=province_id,
                city_id=city_id,
                district_id=district_id,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email

        )
            address = Address.objects.get(pk=address_id)

        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code':RETCODE.DBERR})
        address_dict={
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }
        return http.JsonResponse({'address':address_dict,'code':RETCODE.OK})

    def delete(self,request,address_id ):
        try:
            address=Address.objects.get(pk=address_id)
            address.is_deleted=True
            address.save()
        except Exception as  e:
            pass
        return http.JsonResponse ({'code':RETCODE.OK})


class Person (object):
    name=''
    sex=''
p=Person()
p.name='itcast'

p2 = Person()
p2.name='itheima'


class Phone(object):

    color=''
    price=''


phonex_blue = Phone()
phonex_blue.color=''
phonex_blue.price=''


from django.contrib.auth.mixins import LoginRequiredMixin
class  Modify_passwordView(LoginRequiredMixin,View):
    # 必须是登陆用户才可以访问
    # 如果用户没有登陆，默认会调转到系统的　登陆路由
    #系统的默认登陆路由是：/accounts/login/
    #
    def get(self,request):
        return render(request,'user_center_pass.html')


    def post(self,request):
        old_pwd=request.POST.get('old_password')
        new_pwd=request.POST.get('new_password')
        new_cpwd=request.POST.get('new_password2')

        if not all([old_pwd,new_pwd,new_cpwd]):
        # from django import http
            return http.HttpResponseBadRequest('参数不全')

        if not re.match(r'^[0-9a-zA-Z_-]{8,20}$', old_pwd):
            return http.HttpResponseBadRequest('密码不满足条件')
            # ⑤验证密码
        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_pwd):
            return http.HttpResponseBadRequest('密码格式不正确')
            # ⑥验证确认密码
        if new_cpwd != new_pwd:
            return http.HttpResponseBadRequest('密码不一致')
        if not request.user.check_password(old_pwd):
            return render(request, 'user_center_pass.html', {'origin_password_errmsg': '原始密码错误'})
        if new_pwd == old_pwd:
            return render(request, 'user_center_pass.html', {'change_password_errmsg ': '密码近期设置过，不能再次修改'})
        try :
            request.user.set_password(new_pwd)
            request.user.save()

        except  Exception as  e:

            logger.error(e)
            return render(request,'user_center_pass.html',context={'change_password_errmsg ':'修改密码失败'})

        logout(request)
        response = redirect(reverse('users:login'))
        response.delete_cookie('username')
        return response



#使用修复qq登录的提交

#添加用户数据
class HistoryView(LoginRequiredJSONMixin,View):
    def post(self,request,):
        #接受数据
        user=request.user
        data=json.loads(request.body.decode())
        sku_id=data.get('sku_id')
        #判断验证数据
        try:
            sku=SKU.objects.get(pk=sku_id)
        except SKU.DoesNotExist:
            return  http.JsonResponse({'code':RETCODE.NODATAERR,'errmsg':'暂时无数据'})
        #数据入库
        redis_conn=get_redis_connection("history")
        pl=redis_conn.pipeline()
        #lrem去重
        pl.lrem('history_%s'%user.id,0,sku_id)
        pl.lpush('history_%s'%user.id,sku_id)
        pl.ltrim('history_%s'%user.id,0,4)
        pl.execute()
        return http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})


    def get(self,request):
        #获取用户信息
        user=request.user
        #链接ｒｅｄｉｓ,获取用户信息
        redis_conn=get_redis_connection('history')
        ids=redis_conn.lrange('history_%s'%user.id,0,4)
        #对ｉｄ＇列表进行便利
        skus=[]
        for sku_id in ids:
            sku=SKU.objects.get(pk=sku_id)
            skus.append({
                'id':sku.id,
                'name':sku.name,
                'default_image_url':sku.default_image.url,
                'price':sku.price
            })
        return http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok','skus':skus})

        #返回数据














